﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Caliburn.Micro;
using JY.Wpf.Core.Events;
using JY.Wpf.Core.Tools;

namespace JY.Wpf.Core.ViewModelBases
{
    /// <summary>
    /// 分页窗体ViewModelBase
    /// </summary>
    public abstract class PagedListWindowViewModelBase<T> : WindowViewModelBase, IPage<T> where T : class
    {
        #region # 变量
        #endregion

        #region # 构造器

        /// <summary>
        /// 构造器
        /// </summary>
        protected PagedListWindowViewModelBase()
        {
            this.PageIndex = 1;
            this.PageSize = 10;
            this.CurrentPage = new ObservableCollection<T>();
        }
        #endregion

        #region # 属性

        /// <summary>
        /// 页面数据条数
        /// </summary> 
        [NotifyPropertyChanged]
        public int PageSize { get; set; }

        #region 最大页数——int MaxPageCount

        /// <summary>
        /// 最大页数
        /// </summary>
        [NotifyPropertyChanged]
        public int MaxPageCount { get; set; }
        #endregion

        #region 数据总数——int Count
        /// <summary>
        /// 数据总数
        /// </summary>
        [NotifyPropertyChanged]
        public int Count { get; set; }
        #endregion
        /// <summary>
        /// 当前第几页
        /// </summary>
        [NotifyPropertyChanged]
        public int PageIndex { get; set; }
        /// <summary>
        /// 当前页数据集合
        /// </summary>
        [NotifyPropertyChanged]
        public ObservableCollection<T> CurrentPage { get; }
        #endregion

        #region # 方法

        #region # 查询——void Search()
        /// <summary>
        /// 查询
        /// </summary>
        public virtual void Search()
        {
            this.PageUpdatedAsync(1);
        }
        #endregion

        #region # 翻页——void PageUpdated()
        /// <summary>
        /// 翻页
        /// </summary>
        public void PageUpdated()
        {
            this.PageUpdatedAsync(this.PageIndex);
        }
        #endregion

        #region # 翻页——void PageUpdatedAsync(int index)
        /// <summary>
        /// 翻页
        /// </summary>
        /// <param name="index">页号</param>
        public async void PageUpdatedAsync(int index)
        {
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(true, "加载中..."));
            var data = await this.LoadPageAsync(index);
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(false));
            this.Count = data.Value;
            this.MaxPageCount = (int)Math.Ceiling((double)this.Count / (double)this.PageSize);
            this.PageIndex = index;
            this.CurrentPage.Clear();

            if (data.Key == null) return;
            foreach (var item in data.Key)
            {
                this.CurrentPage.Add(item);
            }
        }
        #endregion

        #region # 加载页数据——Task<IEnumerable<T>> LoadPageAsync(int index, out int maxPageCount)
        /// <summary>
        /// 加载页数据
        /// </summary>
        /// <param name="index">页号</param>
        /// <returns></returns>
        public abstract Task<KeyValuePair<IEnumerable<T>, int>> LoadPageAsync(int index);
        #endregion
        #endregion
    }

    /// <summary>
    /// 分页子窗体ViewModelBase
    /// </summary>
    public abstract class PagedListChildWindowViewModelBase<T> : ChildWindowViewModelBase, IPage<T> where T : class
    {
        #region # 变量
        #endregion

        #region # 构造器

        /// <summary>
        /// 构造器
        /// </summary>
        protected PagedListChildWindowViewModelBase()
        {
            this.PageIndex = 1;
            this.PageSize = 10;
            this.CurrentPage = new ObservableCollection<T>();
        }
        #endregion

        #region # 属性

        /// <summary>
        /// 页面数据条数
        /// </summary> 
        [NotifyPropertyChanged]
        public int PageSize { get; set; }

        #region 最大页数——int MaxPageCount

        /// <summary>
        /// 最大页数
        /// </summary>
        [NotifyPropertyChanged]
        public int MaxPageCount { get; set; }
        #endregion

        #region 数据总数——int Count
        /// <summary>
        /// 数据总数
        /// </summary>
        [NotifyPropertyChanged]
        public int Count { get; set; }
        #endregion
        /// <summary>
        /// 当前第几页
        /// </summary>
        [NotifyPropertyChanged]
        public int PageIndex { get; set; }
        /// <summary>
        /// 当前页数据集合
        /// </summary>
        [NotifyPropertyChanged]
        public ObservableCollection<T> CurrentPage { get; }
        #endregion

        #region # 方法

        #region # 查询——void Search()
        /// <summary>
        /// 查询
        /// </summary>
        public virtual void Search()
        {
            this.PageUpdatedAsync(1);
        }
        #endregion

        #region # 翻页——void PageUpdated()
        /// <summary>
        /// 翻页
        /// </summary>
        public void PageUpdated()
        {
            this.PageUpdatedAsync(this.PageIndex);
        }
        #endregion

        #region # 翻页——void PageUpdatedAsync(int index)
        /// <summary>
        /// 翻页
        /// </summary>
        /// <param name="index">页号</param>
        public async void PageUpdatedAsync(int index)
        {
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(true, "加载中..."));
            var data = await this.LoadPageAsync(index);
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(false));
            this.Count = data.Value;
            this.MaxPageCount = (int)Math.Ceiling((double)this.Count / (double)this.PageSize);
            this.PageIndex = index;
            this.CurrentPage.Clear();

            if (data.Key == null) return;
            foreach (var item in data.Key)
            {
                this.CurrentPage.Add(item);
            }
        }
        #endregion

        #region # 加载页数据——Task<IEnumerable<T>> LoadPageAsync(int index, out int maxPageCount)
        /// <summary>
        /// 加载页数据
        /// </summary>
        /// <param name="index">页号</param>
        /// <returns></returns>
        public abstract Task<KeyValuePair<IEnumerable<T>, int>> LoadPageAsync(int index);
        #endregion
        #endregion
    }

    /// <summary>
    /// 分页ViewModelBase
    /// </summary>
    public abstract class PagedListViewModelBase<T> : ViewModelBase, IPage<T> where T : class
    {
        #region # 变量
        #endregion

        #region # 构造器

        /// <summary>
        /// 构造器
        /// </summary>
        protected PagedListViewModelBase()
        {
            this.PageIndex = 1;
            this.PageSize = 10;
            this.CurrentPage = new ObservableCollection<T>();
        }
        #endregion

        #region # 属性

        /// <summary>
        /// 页面数据条数
        /// </summary> 
        [NotifyPropertyChanged]
        public int PageSize { get; set; }

        #region 最大页数——int MaxPageCount

        /// <summary>
        /// 最大页数
        /// </summary>
        [NotifyPropertyChanged]
        public int MaxPageCount { get; set; }
        #endregion

        #region 数据总数——int Count
        /// <summary>
        /// 数据总数
        /// </summary>
        [NotifyPropertyChanged]
        public int Count { get; set; }
        #endregion
        /// <summary>
        /// 当前第几页
        /// </summary>
        [NotifyPropertyChanged]
        public int PageIndex { get; set; }
        /// <summary>
        /// 当前页数据集合
        /// </summary>
        [NotifyPropertyChanged]
        public ObservableCollection<T> CurrentPage { get; }
        #endregion

        #region # 方法

        #region # 查询——void Search()
        /// <summary>
        /// 查询
        /// </summary>
        public virtual void Search()
        {
            this.PageUpdatedAsync(1);
        }
        #endregion

        #region # 翻页——void PageUpdated()
        /// <summary>
        /// 翻页
        /// </summary>
        public void PageUpdated()
        {
            this.PageUpdatedAsync(this.PageIndex);
        }
        #endregion

        #region # 翻页——void PageUpdatedAsync(int index)
        /// <summary>
        /// 翻页
        /// </summary>
        /// <param name="index">页号</param>
        public async void PageUpdatedAsync(int index)
        {
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(true, "加载中..."));
            var data = await this.LoadPageAsync(index);
            this.EventAggregator.PublishOnUIThread(new BusyIndicatorEvent(false));
            this.Count = data.Value;
            this.MaxPageCount = (int)Math.Ceiling((double)this.Count / (double)this.PageSize);
            this.PageIndex = index;
            this.CurrentPage.Clear();

            if (data.Key == null) return;
            foreach (var item in data.Key)
            {
                this.CurrentPage.Add(item);
            }
        }
        #endregion

        #region # 加载页数据——Task<IEnumerable<T>> LoadPageAsync(int index, out int maxPageCount)
        /// <summary>
        /// 加载页数据
        /// </summary>
        /// <param name="index">页号</param>
        /// <returns></returns>
        public abstract Task<KeyValuePair<IEnumerable<T>, int>> LoadPageAsync(int index);
        #endregion
        #endregion
    }
}
